﻿Public Class Tree
	Inherits TreeView

	Event Activate(ByVal sender As Object)
	Event Delete(ByVal sender As Object)

	Public HasEditableRows As Boolean

	Private Property HandleEnter As Boolean

	Function AddNode(ByVal ParentKey As String, ByVal Key As String, ByVal Text As String) As TreeNode
		Dim Node As TreeNode
		If ParentKey = "" Then
			Node = Nodes.Add(Key, Text)
		Else
			Node = Nodes.Find(ParentKey, True)(0).Nodes.Add(Key, Text)
		End If
		Return Node
	End Function

	Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
		If keyData = Keys.Enter Then
			If HandleEnter Then
				RaiseEvent Activate(Me)
				Return True
			Else
				RaiseEvent Activate(Me)
				If Me.Focused Then Return MyBase.ProcessDialogKey(Keys.Tab)
			End If
		ElseIf keyData = Keys.Delete Then
			RaiseEvent Delete(Me)
		Else
			Return MyBase.ProcessDialogKey(keyData)
		End If
	End Function

	Sub DrawHeader(ByVal G As Graphics, ByVal R As Rectangle)
		G.SmoothingMode = Drawing2D.SmoothingMode.None
		G.FillRectangle(New SolidBrush(Themes.Current.FormColor), R)
		G.DrawLine(New Pen(Color.FromArgb(32, Color.Black)), R.Right - 1, R.Top + 3, R.Right - 1, R.Bottom - 4)
		G.DrawLine(New Pen(Color.FromArgb(16, Color.Black)), R.Left, R.Bottom - 1, R.Right - 1, R.Bottom - 1)
	End Sub

	Private Sub InheritedTree_AfterCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles Me.AfterCheck
		For Each Node As TreeNode In e.Node.Nodes
			Node.Checked = e.Node.Checked
		Next
		Dim N As TreeNode = e.Node
		Do Until N Is Nothing
			Dim Key As String = CheckSubnodes(N)
			N.ImageKey = Key
			N.SelectedImageKey = Key
			N = N.Parent
		Loop
	End Sub

	Function CheckSubnodes(ByVal Node As TreeNode) As String
		If Node.Nodes.Count = 0 Then Return If(Node.Checked, "s1", "s0")
		Dim States(2) As Boolean
		For Each N As TreeNode In Node.Nodes
			States(Mid(CheckSubnodes(N), 2, 1)) = True
		Next
		If States(0) = True And States(1) = False And States(2) = False Then Return "s0"
		If States(1) = True And States(0) = False And States(2) = False Then Return "s1"
		Return "s2"
	End Function

	Private Sub InheritedTree_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
		If e.KeyCode = Keys.Enter Then
			e.Handled = True
			RaiseEvent Activate(Me)
			If Me.Focused And Not HandleEnter Then SendKeys.Send("{TAB}")
		ElseIf e.KeyCode = Keys.Delete Then
			e.Handled = True
			RaiseEvent Delete(Me)
		End If
	End Sub

	Private Sub InheritedTree_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Leave, Me.Enter
		Invalidate()
	End Sub

	Public Sub New()
		DoubleBuffered = True
		DrawMode = TreeViewDrawMode.OwnerDrawAll
		ImageList = New ImageList
		ImageList.ImageSize = New Size(18, 18)
		For i As Integer = 0 To 2
			Dim Bitmap As New Bitmap(18, 18)
			Dim G As Graphics = Graphics.FromImage(Bitmap)
			Dim R As New Rectangle(0, 0, 18, 18)
			R.Inflate(-3, -3)
			Select Case i
				Case 0 : System.Windows.Forms.CheckBoxRenderer.DrawCheckBox(G, R.Location, VisualStyles.CheckBoxState.UncheckedNormal)
				Case 1 : System.Windows.Forms.CheckBoxRenderer.DrawCheckBox(G, R.Location, VisualStyles.CheckBoxState.CheckedNormal)
				Case 2 : System.Windows.Forms.CheckBoxRenderer.DrawCheckBox(G, R.Location, VisualStyles.CheckBoxState.MixedNormal)
			End Select
			ImageList.Images.Add("s" & Trim(i), Bitmap)
		Next
		BorderStyle = Windows.Forms.BorderStyle.None
	End Sub

	Private Sub InheritedTree_DrawNode(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawTreeNodeEventArgs) Handles Me.DrawNode
		e.DrawDefault = True
	End Sub

	Private Sub InheritedTree_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
		If e.KeyChar = Chr(32) Then SelectedNode.Checked = Not SelectedNode.Checked
	End Sub

	Private Sub InheritedTree_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
		Dim Info As TreeViewHitTestInfo = HitTest(e.Location)
		If Info.Node Is Nothing Then Exit Sub
		If Info.Location = TreeViewHitTestLocations.Image Then Info.Node.Checked = Not Info.Node.Checked
	End Sub

	Function GetParentKey(ByVal Key As String) As String
		Dim Node As TreeNode = Nodes.Find(Key, True)(0).Parent
		If Node Is Nothing Then Return ""
		Return Node.Name
	End Function

	ReadOnly Property CheckedNodes() As Object
		Get
			Return Split(GetCheckedNodes(Me), vbCrLf)
		End Get
	End Property

	Private Function GetCheckedNodes(ByVal Parent As Object) As String
		If Parent.Nodes.Count = 0 Then Return If(Parent.Checked, vbCrLf & Parent.Name, "")
		Dim ItemList As String = ""
		For Each Node As TreeNode In Parent.Nodes
			ItemList &= GetCheckedNodes(Node)
		Next
		Return ItemList
	End Function

	Property ItemChecked(ByVal Key As String) As Boolean
		Get
			Return Nodes.Find(Key, True)(0).Checked
		End Get
		Set(ByVal Value As Boolean)
			Try
				Nodes.Find(Key, True)(0).Checked = Value
			Catch ex As Exception
				Warning("Geçersiz anahtar: " & Key)
			End Try
		End Set
	End Property

End Class